package itheima01;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import utils.C3P0Util;

import java.sql.Connection;
import java.sql.SQLException;

/*
    JDBC完成转账功能(加入事务管理)
    场景: tom 欠 jerry 1000元  使用2条update语句
        1.tom-1000
        2.jerry+1000

    以上2条sql应该看成一组(一个整体),必须使用一个事务,必须保证使用同一个Connection对象
        以上2条sql要么全部都执行,要么全部都不执行

    使用DBUtils工具类: 目的简化JDBC的开发步骤,不关心Connection连接对象如何获取,不关心事务管理的事情

    核心类QueryRunner

    空参构造: ---要想使用QueryRunner管理事务,必须使用空参构造

        public QueryRunner(): 可以直接创建对象,但是没有传递Connection连接对象
            所以该对象调用方法,执行增删改查时,必须传Connection连接对象

    有参构造:

        public QueryRunner(DataSource ds) : 创建对象,必须传递连接池对象
            创建QueryRunner对象时,传递连接池对象,执行增删改查的方法时,
            QueryRunner对象会从连接池获取连接对象,但是获取的是哪个连接对象,我们不知道,
            我们也看不见,所以我们不能完成事务管理的工作

    步骤:
        1.空参构造创建QueryRunner对象
        2.获取连接对象
        3.连接对象开启事务
        4.QueryRunner对象执行sql语句获取结果
        5.sql语句正常执行,提交事务,处理结果
        6.sql语句出现问题,回滚事务
        7.关闭资源

    DBUtils中的工具类DbUtils,静态方法:
        public static void	commitAndCloseQuietly(Connection conn): 提交事务,关闭连接,内部进行try-catch异常处理
        public static void	rollbackAndCloseQuietly(Connection conn): 回滚事务,关闭连接,内部进行try-catch异常处理

 */
public class Demo04Account {
    public static void main(String[] args) {
        Connection con = null;
        try {
            //1.空参构造创建QueryRunner对象
            QueryRunner qr = new QueryRunner();

            //2.获取连接对象
            con = C3P0Util.getConnection();

            //3.连接对象开启事务
            con.setAutoCommit(false);

            //定义2条sql语句(2条update语句:扣款,收款)
            String tomSql = "update account set money=money-? where name=?";
            String jerrySql = "update account set money=money+? where name=?";

            //4.QueryRunner对象执行sql语句获取结果
            int tomResult = qr.update(con, tomSql, 1000, "tom");

            System.out.println(1/0);//出异常了

            int jerryResult = qr.update(con, jerrySql, 1000, "jerry");

            //5.sql语句正常执行,提交事务,处理结果
            DbUtils.commitAndCloseQuietly(con);//提交事务,关闭连接,内部进行try-catch异常处理

            if(tomResult>0) {
                System.out.println("tom账户成功扣款1000元~~~");
            } else {
                System.out.println("tom账户扣款1000元失败~~~");
            }

            if(jerryResult>0) {
                System.out.println("jerry账户收款1000元成功~~~");
            } else {
                System.out.println("jerry账户收款1000元失败~~~");
            }


        } catch (Exception e) {
            e.printStackTrace();
            //6.sql语句出现问题,回滚事务
            DbUtils.rollbackAndCloseQuietly(con);//回滚事务,关闭连接,内部进行try-catch异常处理
        }
    }
}
